package com.amt.olcacon.utils;


import cn.hutool.core.bean.BeanUtil;
import com.amt.olcacon.entity.ContributionTree;
import org.openlca.core.DataDir;
import org.openlca.core.database.IDatabase;
import org.openlca.core.database.ImpactMethodDao;
import org.openlca.core.database.ProcessDao;
import org.openlca.core.math.SystemCalculator;
import org.openlca.core.matrix.index.EnviFlow;
import org.openlca.core.matrix.index.TechFlow;
import org.openlca.core.model.CalculationSetup;
import org.openlca.core.model.Process;
import org.openlca.core.model.descriptors.ImpactDescriptor;
import org.openlca.core.results.LcaResult;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import static org.eclipse.persistence.jpa.jpql.Assert.fail;

/**
 * 测试类，用于展示TreeItem类的注释信息并结合计算结果
 */
public class TreeItemByImpactCategory {

    private final IDatabase db = DataDir.get().openDatabase("ecoinvent 3.11 Cutoff System-Processes 2025-01-31");
    private final String PROCESS_UUID = "e9c89a4e-2582-47ea-955f-480bf981785d";

    /**
     * 测试展示TreeItem类的注释信息
     */

    public static void testShowTreeItemComment(List<ContributionTree> contributionTreesImpact,LcaResult result, ImpactDescriptor impact,List<ContributionTree> contributionTreeList) {

            // 1. 创建根节点 (使用public的rootsOf方法)
            List<TreeItem> roots = TreeItem.rootsOf(result, List.of(impact));
            if (!roots.isEmpty()) {
                TreeItem root = roots.getFirst();

                // 2. 获取技术流内部节点（前5个）
                // 使用正确的方式获取技术流，避免使用不存在的toList方法
                List<TechFlow> techFlows = new ArrayList<>();
                for (TechFlow techFlow : result.provider().techIndex()) {
                    techFlows.add(techFlow);
                }

                if (!techFlows.isEmpty()) {
                    List<TreeItem> techNodes = root.techNodesOf(techFlows, 0.01); // 1%的阈值
                    System.out.println("\n[层级2] 技术流内部节点:");
                    for (TreeItem node : techNodes) {
                        final long flowId = node.techFlow().flow().id;
//                        Long providerId = node.techFlow().provider().id;
                        if (flowId < 1000000000L) {
                            continue;
                        }

                        ContributionTree flow = contributionTreesImpact.stream().filter(c -> c.getFlow_id().equals(flowId)).findFirst().orElse(null);
                        if (BeanUtil.isNotEmpty(flow)) {
                            // 3. 获取每个技术流的环境流叶子节点
                            List<EnviFlow> enviFlowsForLeafs = new ArrayList<>();
                            for (EnviFlow enviFlow : result.provider().enviIndex()) {
                                enviFlowsForLeafs.add(enviFlow);
                            }

                            if (!enviFlowsForLeafs.isEmpty()) {
                                List<TreeItem> enviLeafs = node.enviLeafsOf(enviFlowsForLeafs, 0.01); // 10%的阈值
                                System.out.println("     [层级3] 环境流叶子节点:");
                                for (int j = 0; j < enviLeafs.size(); j++) {
                                    TreeItem leaf = enviLeafs.get(j);
                                    if (leaf.enviFlow() != null && leaf.enviFlow().flow() != null) {

//                                    System.out.printf("       %d. 环境流: %s\n",
//                                            j + 1,
//                                            leaf.enviFlow().flow().name);
//                                    System.out.printf("          影响值: %.4f, 贡献比例: %.2f%%\n",
//                                            leaf.impactResult(),
//                                            node.impactResult() != 0 ?
//                                                    (leaf.impactResult() / node.impactResult()) * 100 : 0);
                                        ContributionTree enviFlow = new ContributionTree();
                                        enviFlow.setCalculation_result(flow.getCalculation_result());
                                        enviFlow.setImpact_category(flow.getImpact_category());
                                        enviFlow.setFlow_name(leaf.enviFlow().flow().name);
                                        enviFlow.setFlow_id(leaf.enviFlow().flow().id);
                                        enviFlow.setFlow_type(leaf.enviFlow().flow().flowType.name());
                                        enviFlow.setFlow_ref_id(leaf.enviFlow().flow().refId);
                                        enviFlow.setFlow_property_id(leaf.enviFlow().flow().refFlowPropertyId);
                                        enviFlow.setResult(BigDecimal.valueOf(leaf.impactResult()));
                                        enviFlow.setDirect(BigDecimal.valueOf(leaf.contributionShare()));
                                        enviFlow.setRequired_amount(flow.getRequired_amount());
                                        enviFlow.setProvider("");
                                        enviFlow.setParent_id(flow.getId());
                                        enviFlow.setScaling(node.impactResult() != 0 ? BigDecimal.valueOf((leaf.impactResult() / node.impactResult()) * 100) : BigDecimal.ZERO);
                                        enviFlow.setHas_childs(false);
                                        enviFlow.setImpactCategoryName(impact.name);
                                        enviFlow.setNodeType("enviFlow");
                                        contributionTreeList.add(enviFlow);
                                    }
                                }
                            }
                        }
                    }
                }
            }
    }

    public static void main(String[] args) {

        final IDatabase db = DataDir.get().openDatabase("ecoinvent 3.11 Cutoff System-Processes 2025-01-31");
        final String PROCESS_UUID = "e9c89a4e-2582-47ea-955f-480bf981785d";

        // 1. 从数据库中查找指定UUID的过程
        ProcessDao processDao = new ProcessDao(db);
        Process process = processDao.getForRefId(PROCESS_UUID);

        // 获取影响方法
        var method = new ImpactMethodDao(db).getForId(64262565L);

        // 2. 设置计算配置
        CalculationSetup setup = CalculationSetup.of(process).withImpactMethod(method);

        // 3. 执行核算
        SystemCalculator calculator = new SystemCalculator(db);

        LcaResult result = calculator.calculate(setup);

        ImpactDescriptor impact =result.impactIndex().getForId(64201986L);


//        testShowTreeItemComment(null,result, impact);



    }

}
